Technical Q&A QA1268
Sharpening Full Scene Anti-Aliasing Details


Q: アプリケーションで OpenGL のフルシーンアンチエイリアシングを使うにはどうすればいいのですか?

Mac OS X 上でのフルシーンアンチエイリアシング(FSAA)は、ARB_multisample という OpenGL 拡張によってサポートされています。これは OpenGL ARB(Architecture Review Board)が標準化した、シーンを基準としたアンチエイリアシングの方法で、1 つのポイントで複数のサンプルを採取し、それとカバレッジ値(coverage value)を組み合わせることによって、最終的なフラグメントを得ます。OpenGL 拡張に関する全般的な情報については、テクニカルノートの TN2080 「OpenGL Functionality」 を参照してください。

注:
クライアントアプリケーションで、点または線のアンチエイリアシングを行うだけなら、点と線を対象とした組み込みの OpenGL アンチエイリアシング機を使用するとよいでしょう。OpenGL Specification のセクション 3.4.2 を参照してください。

クライアントアプリケーションは、マルチサンプル拡張でできることとできないことを理解する必要があります。 現在では、サポートハードウェアと利用可能な VRAM に応じて、シーンのサンプル数が 2 倍、4 倍、または 6 倍になります。各サンプルの位置は標準の場合と変わりませんが、最終的な色効果を決めるためにカバレッジ値が追加されています。つまり、ポリゴンのエッジは滑らかになりますが、テクスチャはスーパーサンプリング(つまり、多数の位置でサンプリング)されません。この拡張は、(サンプル数)×(現在のバックバッファサイズ) に等しいメモリを消費するマルチサンプルバッファの作成を必要とし、深度バッファはマルチサンプルバッファサイズに合わせてサイズが拡張され、(サンプル数)×(現在の深度バッファサイズ) バイトのメモリを消費します。

FSAA の設定は比較的簡単ですが、2 つの落とし穴があります。必須のステップが 2 つと任意のステップが 1 つあります。まず、ピクセルフォーマット要求に属性をいくつか追加します。次に、マルチサンプルを有効にします。最後に、クライアントアプリケーションは任意で、マルチサンプルフィルタヒントを OpenGL に渡すことができます。グラフィックカードの機能によっては、このヒントで、より良い結果が得られる場合があります。

まず最初は、ピクセルフォーマット要求に「サンプル」および「サンプルバッファ」属性を追加する必要があります。サンプル属性は、1 つのポイントで採取するサンプルの数、したがってアンチエイリアシングの全般的な品質をコントロールします。指定可能なサンプル値は、現在のところ 2、4、または 6 ですが、クライアントの選択は、VRAM、パフォーマンス、およびグラフィックカードの性能の制約を受けます。サンプルバッファ属性は、マルチサンプルバッファの実際の数をコントロールしますが、現在のところ 1 つのみサポートされています。さらに、ほとんどすべてのクライアントアプリケーションでは「リカバリなし」属性も指定する必要があります。ソフトウェアレンダラが現在のところマルチサンプルをサポートしていないため、通常のソフトウェアフォールバックレンダラによって、OpenGL が有効なピクセルフォーマットを返すのが妨げられますが、この属性によってそれが回避されます。最後に、すべてのハードウェアが ARB マルチサンプル拡張をサポートしているわけではありません。これは、テクニカルノートの TN2080 「OpenGL Functionality」 で説明している、拡張を確認するための標準のテクニックを使用してチェックできます。使用する場合、クライアントアプリケーションは、必要であれば、拡張をサポートするハードウェアだけを指定して、ピクセルフォーマットの検索から、拡張をサポートしていないハードウェアを除外するか、拡張をサポートしていないハードウェアをそのまま検索に残しておくことができます。ハードウェアを除外するには、CGL および NSGL のピクセルフォーマット属性または直接 AGL の aglChoosePixelFormat 関数呼び出しで、ARB_multisample をサポートしているディスプレイだけをピクセルフォーマット選択関数に指定します。その結果、コンテンツがこのレンダラを表示に使用したときには、これらのディスプレイには何もレンダリングされません。拡張をサポートしていないハードウェアをピクセルフォーマット選択に含めると、非サポートディスプレイではマルチサンプリングによるレンダリングではなく、通常のエイリアシングによるレンダリングになります。表 1 に、この説明で挙げた属性の正確な名前を示します。個々の OpenGL インタフェース API の詳細については、テクニカル Q&A の QA1269 「Mac OS X OpenGL Interfaces」 を参照してください。

注:
要求されたサンプル数を使うマルチサンプルバッファを、利用可能な VRAM の範囲内で作成できる場合でも、バッファのサイズが、適切に機能するテクスチャセットを維持する OpenGL の能力に影響を与えるほど大きくなる可能性があます。また、グラフィックカードの利用可能なフィルレートを使いすぎて、パフォーマンスが大幅に低下することもあります。デベロッパは、FSAA を実行するかどうかをユーザが選択できるようにして、サンプル数やフィルタヒントといったマルチサンプリングの品質を制御するスライダーのような単純なコントロールをユーザに提供することをお勧めします(以下を参照)。


表 1. ピクセルフォーマットの定数

 
CGL NSOpenGLPixelFormat AGL
サンプル
kCGLPFASamples NSOpenGLPFASamples AGL_SAMPLES_ARB
サンプルバッファ
kCGLPFASampleBuffers NSOpenGLPFASampleBuffers AGL_SAMPLE_BUFFERS_ARB
リカバリなし
kCGLPFANoRecovery NSOpenGLPFANoRecovery AGL_NO_RECOVERY

ピクセルフォーマットとコンテクストの設定コードは、クライアントアプリケーションで通常使用するものによく似います。リスト 1 に、3 つの OpenGL インタフェース API を対象とするピクセルフォーマット作成コードを示します。3 つのリストすべてについて、属性の処理は同じですが、関数と定数の名前が少し異なります。コンテクスト作成が API ごとに若干異なるため、利用可能なスクリーンを指定する方法も異なります。しかし、その結果は同じで、有効な指定スクリーンを含み、ソフトウェアフォールバックなしでスクリーンのレンダラのセットを示すピクセルフォーマットになります。

リスト 1a. アンチエイリアス用の CGL ピクセルフォーマットとコンテクスト設定

#include <OpenGL/OpenGL.h>

CGLPixelFormatAttribute attribs[] = { kCGLPFADisplayMask, 0,
                                      kCGLPFAFullScreen,
                                      kCGLPFADoubleBuffer,
                                      kCGLPFASampleBuffers, 1,
                                      kCGLPFASamples, 2,
                                      kCGLPFANoRecovery,
                                      0 };
CGLPixelFormatObj pixelFormat = NULL;
CGLContextObj context = NULL;
long numPixelFormats = 0;
 
// デモのためにメインディスプレイを使用
// ディスプレイモードを取得、設定する必要がある(このコードには示していない)
// ピクセルフォーマット属性でディスプレイマスクを設定
attribs[1] = CGDisplayIDToOpenGLDisplayMask (CGMainDisplayID ());

CGLChoosePixelFormat (attribs, &pixelFormat, &numPixelFormats));

// コンテクストを作成
if (pixelFormat) {
    CGLCreateContext (pixelFormat, NULL, &context);
    CGLDestroyPixelFormat (pixelFormat);
}

リスト 1b. アンチエイリアス用の NSOpenGL ピクセルフォーマットとコンテクスト設定

#import <Cocoa/Cocoa.h>

@implementation BasicOpenGLView

+ (NSOpenGLPixelFormat*)defaultPixelFormat
{
    NSOpenGLPixelFormatAttribute attributes [] = {
        NSOpenGLPFAWindow,
        NSOpenGLPFADoubleBuffer,
        NSOpenGLPFASampleBuffers, 1, 
        NSOpenGLPFASamples, 2,
        NSOpenGLPFANoRecovery,
        (NSOpenGLPixelFormatAttribute)nil
    };
    return [[[NSOpenGLPixelFormat alloc] 
                        initWithAttributes:attributes] autorelease];
}

-(id) initWithFrame: (NSRect) frameRect
{
    NSOpenGLPixelFormat *pixelFormat = [BasicOpenGLView defaultPixelFormat];

    self = [super initWithFrame: frameRect pixelFormat: pixelFormat];
    return self;
}

// ほかのクラスメソッドをここに定義

@end

リスト 1c. アンチエイリアス用の AGL ピクセルフォーマットとコンテクスト設定

#include <AGL/agl.h>

GLint attribs[] = { AGL_RGBA, AGL_DOUBLEBUFFER, 
                    AGL_SAMPLE_BUFFERS_ARB, 1, 
                    AGL_SAMPLES_ARB, 2, 
                    AGL_NO_RECOVERY, 
                    AGL_NONE };
     
AGLPixelFormat pixelFormat = NULL;
AGLContext context = NULL;

// サポートされているディスプレイの GDHandles のリストをここで指定できる
pixelFormat = aglChoosePixelFormat (NULL, 0, attribs);

// コンテクストを作成
if (pixelFormat) {
    context = aglCreateContext (pixelFormat, NULL);
    aglDestroyPixelFormat (pixelFormat);
}

マルチサンプル対応のコンテクストを作成したら、glEnable に対して GL_MULTISAMPLE_ARB 機能を指定してマルチサンプリングを有効にします。マルチサンプルバッファをピクセルフォーマットで作成した場合は、マルチサンプリングが有効かどうかにかかわらず、レンダリングは必ずマルチサンプルバッファを通じて行われます。マルチサンプルを無効にすると、すべてのカバレッジ値が 1 に設定され、非マルチサンプルレンダリングと同等の結果となります。対応するバッファがピクセルフォーマットで作成されていなければ、マルチサンプルを有効にしても何も起こりません。

注:
現在のところ、Radeon 9800 Pro と Radeon 9600 Pro より前の ATI グラフィックハードウェアでは、マルチサンプリングを有効にするフラグをサポートしていないため、すべての場合において有効のままとなります。クライアントアプリケーションでは、必要に応じてコンテクストを有効にするフラグを正しく設定することをお勧めしますが、ATI の特定のハードウェアでは glDisable が無視される場合があることを念頭においてください。

マルチサンプリングのレンダリングヒントは、GL_MULTISAMPLE_FILTER_HINT_NV 拡張によってサポートされます。GL_MULTISAMPLE_FILTER_HINT_NV をターゲットとして使用することで、標準の glHint API に高速または高品質レンダリングのヒントを追加できます。ヒントの指定は任意であり、指定したヒントに対応できないハードウェアもありますが、クライアントアプリケーションが優先する方向性に関してより多くの情報が OpenGL に与えられるため、クライアントアプリケーションは適宜、可能であればヒントを指定するべきです。具体的にいえば、クライアントアプリケーションは GL_FASTEST または GL_NICEST のどちらのレンダリングアルゴリズムを使用するべきか指示して、ハードウェアの能力の範囲内で出力ができるかぎり最適化されるようにします。サポートされていないヒントを指定してもペナルティはなく、エラーも返されません。リスト 2 に、マルチサンプルを有効にし、OpenGL にレンダリングヒントを送る最後の 2 ステップのコードを示します。

リスト 2. マルチサンプルの有効化とレンダリングヒントの設定

#include <OpenGL/gl.h>
#include <OpenGL/glext.h>

glEnable (GL_MULTISAMPLE_ARB);
glHint (GL_MULTISAMPLE_FILTER_HINT_NV, GL_NICEST);

これで、Mac OS X 上でフルシーンアンチエイリアシングを実現する ARB_multisample OpenGL 拡張の使用に関する説明は終わりです。OpenGL 対応アプリケーションでは、FSAA のコントロールをユーザに提供することで、より優れたユーザエクスペリエンスを簡単に提供することができます。設定と対応の作業は簡単であり、ユーザが操作できるようにすることで、個々のシステムの能力やユーザの望みに合わせてユーザエクスペリエンスを最適化することができます。


[2003 年 10 月 10 日]